
package com.huawei.classroom.student.h13;

import java.io.Closeable;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

/**
 * 在本包下增加合适的类和方法，使得Test类能够测试通过 
 * 
 * 不要引用jdk1.8以外第三方的包
 * 
 * @author cjy
 *
 */
public class Analysis {
	private String[] chapters = null;

	/**
	 * @throws Exception
	 * 
	 */
	public Analysis(String filename) throws Exception {	
		chapters = splitContentToChapter(readFromTxt(filename));
	}

	/**
	 * 提示 ：将一个文本文件读取到一个字符串中返回
	 * 
	 * @param filename
	 *            红楼梦文本文件的全路径名
	 * @return 文本的内容
	 */
	private String readFromTxt(String filename) throws Exception {
		Reader reader = null;
		try {
			StringBuffer buf = new StringBuffer();
			char[] chars = new char[1024];
			// InputStream in=new FileInputStream(filename);

			reader = new InputStreamReader(new FileInputStream(filename), "UTF-8");
			int readed = reader.read(chars);
			while (readed != -1) {
				buf.append(chars, 0, readed);
				readed = reader.read(chars);
			}
			return buf.toString();
		} finally {
			close(reader);
		}
	}
	
	/**
	 * 返回红楼梦中出现频率最高的N个次，频率从高到低排列（所谓词就是两个相邻的汉字）
	 * @param n
	 * @return
	 */
	public List<String> getTopNWords(  int n){
		Map<String, Integer> map = new HashMap<String, Integer>();
		for(int i=0; i<chapters.length; i++) {
			for(int j=0; j<chapters[i].length()-1; j++) {
				if(judge(chapters[i].charAt(j)) || judge(chapters[i].charAt(j+1))) {
					//j++;
					continue;
				}
				String temp = chapters[i].substring(j, j+2);
				map.put(temp, (map.get(temp) == null ? 1 : map.get(temp) + 1));
			}
		}
		List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
		Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
			@Override
			public int compare(Map.Entry<String, Integer> a1, Map.Entry<String, Integer> a2) {
				return a2.getValue() - a1.getValue();
			}
		});
		//debug
		/*
		for(int i=0; i<n; i++) {
			System.out.println(list.get(i).getKey()+" "+list.get(i).getValue());
		}
		*/
			
		List<String> fina_list = new ArrayList<String>(n);
		for(int i=0; i<n; i++) {
			String t = list.get(i).getKey();
			fina_list.add(t);
		}
		return fina_list;
	}
	
	/**
	 * @param a
	 * @return
	 */
	public boolean judge(char a) {
		if(a == ' ' || a == '：' || a == '\t' || a == '，' || 
				a == '\n' || a == '"' || a == '《' || a == '》' || 
				a == '.' || a == '？' || a == '。' || a == '“' || 
				a == '”' || a == '‘' || a == '’' || a == ':' || 
				a == ',' || a == '！' || a == '；' || a == '．')
			return true;
		return false;
	}
	/**
	 * 关闭输入输入流
	 * 
	 * @param inout
	 */
	private void close(Closeable inout) {
		if (inout != null) {
			try {
				inout.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	/**
	 * 提示 将红楼梦文本文件拆分为120个章节的方法
	 * 
	 * @param content
	 * @return 返回120个元素的字符串数组
	 */
	private String[] splitContentToChapter(String content) {
		// 提示 使用 content.split(" 第[一,二,三,四,五,六,七,八,九,十,零]{1,5}回 ");正则表达拆分
		// 百度一下正则表达式
		String contents[] = content.split(" 第[一,二,三,四,五,六,七,八,九,十,零]{1,5}回 ");
		String ss[] = new String[contents.length - 1];
		for(int i=0; i<ss.length; i++) {
			ss[i] = contents[i+1];
		}
		return ss;
	}

	 
	/**
	 * 统计红楼梦章节字符串str出现的频率
	 * @param str
	 * @return
	 * @throws Exception
	 */
	public int[] getStringFrequent(String str) throws Exception {
		int[] result = new int[chapters.length];
		String[] copy_chapters = new String[chapters.length];
		System.arraycopy(chapters, 0, copy_chapters, 0, chapters.length); 
		int str_num = str.length();
		for(int i=0; i<chapters.length; i++) {
			result[i] = (chapters[i].length() - copy_chapters[i].replace(str, "").length()) / str_num;
		}
		return result;
	}

}
